Option Strict Off
Option Explicit On
Imports System
Imports System.Drawing
Imports System.Reflection
Imports VB = Microsoft.VisualBasic
Friend Class Form1
	Inherits System.Windows.Forms.Form
  Private Declare Function MessageBeep Lib "user32" (ByVal wType As Integer) As Integer
	Private Declare Function sndPlaySound Lib "winmm.dll"  Alias "sndPlaySoundA"(ByVal lpszSoundName As String, ByVal uFlags As Integer) As Integer
  Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Integer)

  Const SND_SYNC As Short = &H0S
	Const SND_ASYNC As Short = &H1s
	Const SND_NODEFAULT As Short = &H2s
  Const MB_ICONEXCLAMATION As Short = &H20
  Const MB_ICONASTERISK As Short = &H40

  ' my variables
	Const N As Short = 10 ' game board dimension
  Dim blueindex, redindex As Short
  Public blue As Panel()
  Public red As Panel()

  ' online game
	Dim OPTSelected As Boolean
	Dim min, hr, sec As Integer
  Dim hrs, mins As Integer
	Dim secs As String
	Dim nMoves As Integer
	Dim nPlayer As Integer
	Dim sendok As Boolean
  Dim oGarb2, oGarb1, oRepl As Panel, bMoveOnEat As Boolean
  Public PlayOffline As Boolean ' offline or online game
  Public Connected As Boolean ' am i connected
  Public Host As Boolean ' am i host or guest ?
  Public HostName As String ' remote host (i am guest)
  Public TryConnect As Boolean ' i am trying to connect
  Public NickName As String
  Public VisitorName As String
  Public WaitForPlayer As Boolean ' if True blue have to play,if False red
  Public MoveFromNetwork As Boolean ' we move the piece directed by network command
  Public sWinner As String ' who won
  Public OpponentReady, OursReady As Boolean
  Public mSavedData As String ' saved game status
  Public mFormPiecesOut As FormPiecesOut
  Const DEBUGGING As Boolean = True
  Dim delProc As New DelProcessMessage(AddressOf ProcessMessage)
  Private Sub SockClient_DataArrival(ByVal sender As Winsock_Control.Winsock, ByVal BytesTotal As Integer) Handles SockClient.DataArrival
    'On Error Resume Next
    Dim strdata As String = ""
    SockClient.GetData(strdata)
    Me.Invoke(delProc, New Object() {strdata})
  End Sub
  Public Delegate Sub DelProcessMessage(ByVal strdata As String)
  Sub ProcessMessage(ByVal strdata As String)
    Dim message As String
    Dim pos1, pos2 As Integer
    pos1 = 1
    Do
      pos2 = InStr(pos1 + 1, strdata, "#")
      If pos2 < 1 Then pos2 = Len(strdata) + 1
      message = Mid(strdata, pos1, pos2 - pos1)
      Call ProcessDataArrived(message)
      pos1 = pos2
    Loop While pos2 < Len(strdata)
  End Sub

  Sub ProcessDataArrived(ByRef strdata As String)
    Dim code1, code2 As String
    If Mid(strdata, 1, 9) = "#010text_" Then
      If frmChat1.Visible = False Then frmChat1.Show()
      frmChat1.AddMessageToList(VisitorName & " Said >> " & Mid(strdata, 10, Len(strdata) - 9))
    Else
      code1 = Mid(strdata, 1, 14)
      code2 = Mid(strdata, 1, 18)
      Select Case code1
        Case "#010_code_arrg" : Call GetOpponentArrangement(strdata) 'msg sent by both
        Case "#010_code_resu" : mSavedData = Mid(strdata, 15) 'msg sent by Guest
        Case "#010_code_move" : MakeMove(strdata) 'msg sent by both
        Case "#010_code_tagc" : ChangeTag(strdata) 'msg sent by both
      End Select
      Select Case code2
        Case "#020code_wantnewga" : WantaNewGame(strdata)
        Case "#020code_kfornewga" : StartNewGame(strdata)
        Case "#020code_refunewga" : RefuseNewGame()
        Case "#020code_okconnect" : RequestGame() ' msg sent by Host
        Case "#020code_wantagame" : WantaGame(strdata) ' msg sent by Guest
        Case "#020code_resumgame" : WantaGame(strdata) ' msg sent by Guest
        Case "#020code_okforgame" : OkGame(strdata) ' msg sent by Host, wait for arrangement now
        Case "#020code_okforresu" : OkGame2(strdata) ' msg sent by Host, calls StartNewGame
        Case "#020code_refusgame" : TerminateGame() ' msg sent by Host
        Case "#020code_receiveok" : StartNewGame(strdata) ' msg sent by Guest
        Case "#020code_quitegame" : QuitTheGame()
      End Select
    End If
  End Sub
  Private Sub OnChat()
    Dim frm As New frmChat1
    frm.Show()
  End Sub

  Private Sub Command1_Click()
    'frmChat1.AddMessageToList "eheeee"
  End Sub
  Private Sub SockListen_ConnectionRequest(ByVal sender As Winsock_Control.Winsock, ByVal requestID As System.Net.Sockets.Socket) Handles SockListen.ConnectionRequest
    'On Error Resume Next
    'If SockClient.GetState <> Winsock_Control.WinsockStates.Closed Then SockClient.Close()
    SockClient.Accept(requestID)
    Me.BeginInvoke(New DelUIMethod(AddressOf ConnectionEstablished))
  End Sub
  Public Delegate Sub DelUIMethod()
  Sub ConnectionEstablished()
    SockClient.Send("#020code_okconnect" & NickName)
    GameMode = enumGameMode.NOTSTARTED
    Timer3.Enabled = True : Timer3.Interval = 1000
    System.Windows.Forms.Application.DoEvents()
  End Sub

  ' guest calls it
  Public Sub RequestGame()
    mSavedData = ""
    ' only host sends this message (#020code_okconnect)
    If Host = True Then Host = False
    Call Sleep(100)
    Dim f As IO.StreamReader
    Dim line As String
    If frmNewGame.chkResume.CheckState = 0 Then
      SockClient.Send("#020code_wantagame" & NickName)
    Else
      ' load saved game
      f = New IO.StreamReader(frmNewGame.m_SavedGame)
      line = f.ReadLine
      SockClient.Send("#020code_resumgame" & NickName & "," & line)
      mSavedData = f.ReadLine
      f.Close()
      f = Nothing
    End If
    System.Windows.Forms.Application.DoEvents()
  End Sub
  ' host calls it
  Private Sub WantaGame(ByVal strdata As String)
    Dim IncomingName, code2 As String
    code2 = Mid(strdata, 1, 18)
    Dim rep As MsgBoxResult = MsgBoxResult.Cancel
    Dim arrRes As String()
    Call Sleep(100)
    ' only guest sends these messages
    If Not Host Then Host = True
    ' accept game request??
    If Not DEBUGGING Then
      If code2 = "#020code_wantagame" Then
        IncomingName = Mid(strdata, 19)
        rep = MsgBox(My.Resources.MSG_ACCEPT_NEW_1 & IncomingName & My.Resources.MSG_ACCEPT_NEW_2, MsgBoxStyle.YesNoCancel, My.Resources.MSG_CONNECTION)
      ElseIf code2 = "#020code_resumgame" Then
        arrRes = Split(Mid(strdata, 19), ",")
        rep = MsgBox(My.Resources.MSG_RESUME_1 & arrRes(0) & My.Resources.MSG_RESUME_2 & arrRes(1) & My.Resources.MSG_RESUME_3 & arrRes(2) & My.Resources.MSG_ACCEPT_NEW_2, MsgBoxStyle.YesNoCancel, My.Resources.MSG_CONNECTION)
      End If
      If rep = MsgBoxResult.Cancel Or rep = MsgBoxResult.No Then
        Call PlaySound("TURKEY.WAV")
        SockClient.Send("#020code_refusgame")
        System.Windows.Forms.Application.DoEvents()
        Exit Sub
      End If
    End If
    If code2 = "#020code_wantagame" Then
      SockClient.Send("#020code_okforgame" & NickName)
    ElseIf code2 = "#020code_resumgame" Then
      SockClient.Send("#020code_okforresu" & NickName)
    End If
    Call PlaySound("youcanwin.wav")
    System.Windows.Forms.Application.DoEvents()
  End Sub
  Private Sub TerminateGame()
    'On Error Resume Next
    MyMsgBox(My.Resources.MSG_HOST_REFUSED)
    Call PlaySound("TURKEY.WAV")
    If SockClient.GetState <> Winsock_Control.WinsockStates.Closed Then SockClient.Close()
  End Sub
  ' opponent has the blue army
  Private Sub GetOpponentArrangement(ByRef sarr As String)
    Dim i As Integer
    'On Error GoTo errarr
    'Try
    If Not GameMode = enumGameMode.ARRANGEMENT Then Exit Sub
    sarr = Mid(sarr, 15)
    Dim arrPos As String()
    arrPos = Split(sarr, "-")
    For i = 0 To 4 * N - 1
      blue(i).Tag = CInt(arrPos(i))
    Next
    Call PlaySound("Event.wav")
    If Not DEBUGGING And Not OursReady Then MyMsgBox(My.Resources.MSG_OTHER_PLAYER_READY)
    OpponentReady = True
    mFormPiecesOut.panBlue.ZeroPiecesLabels()
    mFormPiecesOut.panRed.ZeroPiecesLabels()
    If OursReady Then Call InitGame()
    'Catch ex As Exception
    '  MyMsgBox(My.Resources.MSG_POS_INITIALIZATION_ERROR)
    'End Try
  End Sub
  ' we have the red army when playing online
  Private Sub SendArrangement()
    Dim i As Integer
    'On Error Resume Next
    Dim sarr As String
    Dim arrPos(4 * N - 1) As String
    For i = 0 To 4 * N - 1
      arrPos(i) = CStr(red(i).Tag)
    Next
    sarr = "#010_code_arrg" & String.Join("-"c, arrPos)
    'If DEBUGGING Then MyMsgBox(sarr)
    SockClient.Send(sarr)
  End Sub
  Private Sub QuitTheGame()
    If GameMode = enumGameMode.PLAYMODE Or GameMode = enumGameMode.ARRANGEMENT Then
      MyMsgBox(VisitorName & My.Resources.MSG_HAS_LEFT)
      GameMode = enumGameMode.ABORTED
    End If
  End Sub
  Private Sub RefuseNewGame()
    MyMsgBox(My.Resources.MSG_OPPONENT_REFUSED)
  End Sub
  Private Sub WantaNewGame(ByRef strdata As String)
    Dim rep As MsgBoxResult
    Dim strtemp As String
    rep = MsgBox(VisitorName & My.Resources.MSG_WANTS_REPEAT, MsgBoxStyle.YesNo, My.Resources.MSG_NEW_GAME)
    If rep = MsgBoxResult.Yes Then ' accept new game
      SockClient.Send("#020code_kfornewga" & NickName)
      strtemp = Mid(strdata, 19, Len(strdata) - 18)
      If strtemp = "No" Then ' opponent is not host, we are
        Host = True
      Else
        Host = False
      End If
      PlayOffline = False
      Connected = True
      Call PrepareGame()
    Else ' refuse for new game
      SockClient.Send("#020code_refunewga")
    End If
  End Sub
  ' called by guest
  Private Sub OkGame(ByRef strdt As String)
    'On Error Resume Next
    Call PlaySound("youcanwin.wav")
    SockClient.Send("#020code_receiveok" & NickName)
    System.Windows.Forms.Application.DoEvents()
    Call Sleep(100)
    StartNewGame(strdt)
  End Sub
  Private Sub OkGame2(ByRef strdt As String)
    'On Error Resume Next
    Call PlaySound("youcanwin.wav")
    SockClient.Send("#010_code_resu" & mSavedData)
    System.Windows.Forms.Application.DoEvents()
    Call Sleep(100)
    SockClient.Send("#020code_receiveok" & NickName)
    System.Windows.Forms.Application.DoEvents()
    StartNewGame(strdt)
  End Sub
  ' we moved a pice, send our move over the network, wait for other player
  Private Sub PieceMoved(ByRef MoveString As String)
    'On Error Resume Next
    SockClient.Send(MoveString)
    'MsgBox "Sending move: " & Mid(MoveString, 15) ' debug
    System.Windows.Forms.Application.DoEvents()
    nPlayer = nPlayer + 1
    sblBattleInfo.Text = ""
  End Sub
  ' change of tag sent through the network
  Private Sub ChangeTag(ByRef strdat As String)
    Dim dat As String
    Dim ind, pos, tag1 As Integer
    dat = Mid(strdat, 15)
    pos = InStr(1, dat, ",")
    ind = CInt(Mid(dat, 1, pos - 1))
    tag1 = CInt(Mid(dat, pos + 1))
    blue(ind).Tag = tag1
  End Sub
  Private Function ToPixF(ByVal pos As Single) As Integer
    Dim pix As Integer = CInt(CSng(Me.board.Size.Width) * pos / N)
    Return pix
  End Function
  Private Function ToPix(ByVal pos As Integer) As Integer
    Dim pix As Integer = CInt(Me.board.Size.Width * pos / N)
    Return pix
  End Function
  Private Function ToPos(ByVal pix As Integer) As Integer
    Return Math.Round(CDbl(N * pix) / Me.board.Size.Width)
  End Function
  Private Function ToPosF(ByVal pix As Integer) As Single
    Return CSng(N * pix) / Me.board.Size.Width
  End Function
  ' the other player made a move, we took it over the network. Show it
  Private Sub MakeMove(ByRef strdat As String)
    'On Error Resume Next
    Dim p4, p2, p1, p3 As Integer
    Dim redTargetIndex As Integer
    p1 = InStr(1, strdat, "-", CompareMethod.Binary)
    p2 = InStr(p1 + 1, strdat, "-", CompareMethod.Binary)
    p3 = InStr(p2 + 1, strdat, "-", CompareMethod.Binary)
    p4 = InStr(p3 + 1, strdat, "-", CompareMethod.Binary)
    Dim ind As Integer
    Dim xold, yold As Integer
    Dim xnew, ynew As Integer
    Dim bTargetFound As Boolean
    ind = Val(Mid(strdat, 14 + 1, p1 - 14 - 1))
    xold = Val(Mid(strdat, p1 + 1, p2 - p1 - 1))
    yold = Val(Mid(strdat, p2 + 1, p3 - p2 - 1))
    xnew = Val(Mid(strdat, p3 + 1, p4 - p3 - 1))
    ynew = Val(Mid(strdat, p4 + 1))
    'MsgBox "Got move: " & ind & "-" & xold & "-" & yold & "-" & xnew & "-" & ynew ' debug
    ' positions taken are with respect of the red army, transform them with respect to blue army
    xold = N - 1 - xold
    yold = N - 1 - yold : xnew = N - 1 - xnew : ynew = N - 1 - ynew
    ' sanity check
    If xold <> ToPos(blue(ind).Left) Or yold <> ToPos(blue(ind).Top) Then
      MessageBox.Show("ALERT: Blue piece should be in " & ToPos(blue(ind).Left) & "," & ToPos(blue(ind).Top) & " position" & vbCrLf & "Now it is in " & ToPos(xold) & "," & ToPos(yold) & " position")
    End If
    'simulate manual drag & drop
    MoveFromNetwork = True
    redTargetIndex = FindTargetPiece(red, xnew, ynew)
    bTargetFound = (redTargetIndex >= 0)
    If bTargetFound Then
      ' we have been attacked !!
      Dim data As New DataObject(blue(ind))
      Dim e As New DragEventArgs(data, 0, xnew, ynew, DragDropEffects.Move, DragDropEffects.Move)
      red_DragDrop(red(redTargetIndex), e)
    Else
      ' blue moves in the board
      Dim data As New DataObject(blue(ind))
      Dim e As New DragEventArgs(data, 0, xnew, ynew, DragDropEffects.Move, DragDropEffects.Move)
      board_DragDrop(board, e)
    End If
    'end simulate manual drag & drop
    MoveFromNetwork = False
    System.Windows.Forms.Application.DoEvents()
  End Sub
  Function FindTargetPiece(ByRef ColorPiece As Panel(), ByVal xnew As Integer, ByVal ynew As Integer) As Integer
    Dim j As Integer
    Dim target As Integer = -1
    For j = 0 To 4 * N - 1
      If ToPos(ColorPiece(j).Left) = xnew AndAlso _
         ToPos(ColorPiece(j).Top) = ynew Then
        target = j
        Exit For
      End If
    Next
    Return target
  End Function
  Private Sub SockClient_Error(ByVal sender As Winsock_Control.Winsock, ByVal Description As String, ByVal Method As String, ByVal myEx As String) Handles SockClient.HandleError
    MyMsgBox("Connection error: " & Description)
  End Sub
  Private Sub MyMsgBox(ByVal message As String)
    MessageBox.Show(message, "Stratego", MessageBoxButtons.OK, MessageBoxIcon.Information)
  End Sub
  Private Sub Timer3_Tick(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Timer3.Tick
    Dim sMin, sSec, sHr As String
    If PlayOffline = False Then
      CheckDisconnectOrReconnect()
    End If
    Call CheckIfNoMovePossible()
    If GameMode = enumGameMode.FINISHED Then
      Timer3.Enabled = False
      Call FinishGame()
    End If
    tsbSave.Enabled = Not PlayOffline And (GameMode = enumGameMode.PLAYMODE Or GameMode = enumGameMode.DISCONNECTED Or GameMode = enumGameMode.ABORTED)
    tsbStop.Enabled = (GameMode = enumGameMode.PLAYMODE)
    If GameMode = enumGameMode.ABORTED Then tsbReady.Enabled = True
    Dim sStatus As String = ""
    If Not GameMode = enumGameMode.PLAYMODE Then
      'If sb1.Style = mscomctl.SbarStyleConstants.sbrNormal Then sb1.Style = mscomctl.SbarStyleConstants.sbrSimple
      Select Case GameMode
        Case enumGameMode.ARRANGEMENT
          sStatus = My.Resources.MSG_STATUS_ARRANGEMENT
        Case enumGameMode.DISCONNECTED
          sStatus = My.Resources.MSG_STATUS_DISCONNECTED
        Case enumGameMode.ABORTED
          sStatus = My.Resources.MSG_STATUS_ABORTED
        Case enumGameMode.FINISHED
          sStatus = My.Resources.MSG_STATUS_FINISHED & IIf(sWinner = "red", NickName, VisitorName)
        Case enumGameMode.NOTSTARTED
          sStatus = My.Resources.MSG_STATUS_NOT_STARTED
      End Select
      sb1.Text = sStatus
      Exit Sub
    End If
    ' we are in play mode, make normal status bar with panes
    'If sb1.Style = mscomctl.SbarStyleConstants.sbrSimple Then sb1.Style = mscomctl.SbarStyleConstants.sbrNormal
    ' we are in play-mode, show time elapsed
    sec = sec + 1
    If sec = 60 Then
      min = min + 1 : sec = 0
    End If
    If min = 60 Then
      hr = hr + 1 : min = 0
    End If
    sSec = MakeTimeString(sec)
    sMin = MakeTimeString(min)
    sHr = MakeTimeString(hr)
    sblTime.Text = "Time: " & sHr & ":" & sMin & ":" & sSec
  End Sub
  Private Sub TimerGarbage_Tick(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles TimerGarbage.Tick
    Dim x, y As Short
    ' garbage collection ! (remove eaten piece from board)
    If Not oGarb1 Is Nothing AndAlso Not oGarb2 Is Nothing Then 'eat both
      oGarb1.Location = New Point(ToPix(-2), ToPix(-2))
      oGarb1.BackgroundImage = Nothing
      oGarb2.Location = New Point(ToPix(-2), ToPix(-2))
      oGarb2.BackgroundImage = Nothing
    ElseIf Not oGarb1 Is Nothing Then
      x = oGarb1.Left : y = oGarb1.Top
      oGarb1.Location = New Point(ToPix(-2), ToPix(-2))
      oGarb1.BackgroundImage = Nothing
      If bMoveOnEat AndAlso oRepl IsNot Nothing Then
        oRepl.Location = New Point(x, y)
      End If
    End If
    TimerGarbage.Enabled = False
  End Sub
  Private Function MakeTimeString(ByRef x As Integer) As String
    MakeTimeString = CStr(x)
    If Len(MakeTimeString) = 1 Then MakeTimeString = "0" & MakeTimeString
  End Function
  Private Sub CheckDisconnectOrReconnect()
    Dim ret As Integer
    'On Error Resume Next
    ' we are disconnected,try to connect
    Timer3.Enabled = False
    If SockClient.GetState <> Winsock_Control.WinsockStates.Connected AndAlso Connected Then
      SockClient.Close()
      ret = MsgBox(My.Resources.MSG_DISCONNECTED, MsgBoxStyle.YesNo)
      If ret = MsgBoxResult.Yes Then
        GameMode = enumGameMode.DISCONNECTED
        NameNIP.Connect()
        frmTryConnect.GetinitWaitting()
        frmTryConnect.ShowDialog()
        ' todo
      Else
        GameMode = enumGameMode.DISCONNECTED
        Connected = False
        ' Call HideRed: Call HideBlue
      End If
    ElseIf SockClient.GetState = Winsock_Control.WinsockStates.Connected And GameMode = enumGameMode.DISCONNECTED Then
      MyMsgBox(My.Resources.MSG_REESTABLISH_CONNECTION)
      GameMode = enumGameMode.PLAYMODE
      Connected = True
    End If
    Timer3.Enabled = True
  End Sub
  ' -------------------------------------------------------------------------------------------------------------------------------------------------------------------
  ' ------------------------------------                                     START OF GAME                   ------------------------------------
  ' -------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Private Sub OnStart()
    Dim r As Integer
    Dim bStartNow As Boolean
    If GameMode = enumGameMode.ARRANGEMENT Or GameMode = enumGameMode.PLAYMODE Then
      r = MsgBox(My.Resources.MSG_IN_PROGRESS, MsgBoxStyle.YesNoCancel, My.Resources.MSG_NEW_GAME)
      bStartNow = (r = MsgBoxResult.Yes)
    Else
      bStartNow = True
    End If
    If bStartNow Then
      'TurnLabel.Visible = False: turn(0).Visible = False: turn(1).Visible = False
      frmNewGame.Close()
      frmNewGame.ShowDialog()
      frmNewGame.Refresh()
      If frmNewGame.m_Response = "cancel" Then Exit Sub
    End If
  End Sub
  Private Sub OnSave()
    Dim f As IO.StreamWriter
    Dim row As String = ""
    Dim i As Integer
    With cdlSaveGame
      .Filter = "Stratego saved game files (*.str)|*.str|All files (*.*)|*.*"
      If .ShowDialog() = Windows.Forms.DialogResult.OK Then
        Try
          f = New IO.StreamWriter(.FileName, False)
          f.WriteLine(NickName & My.Resources.MSG_AGAINST & VisitorName & "," & CStr(Now))
          ' write blue data first, then red data
          ' for each player we save: tags (types of pieces), positions,numbers of eaten pieces
          ' blue data
          For i = 0 To 4 * N - 1
            row = row & Chr(CDbl(blue(i).Tag) + 100)
          Next i
          For i = 0 To 4 * N - 1
            row = row & Chr(ToPos(blue(i).Top) * N + ToPos(blue(i).Left) + 100)
          Next i
          For i = 0 To 11
            row = row & Chr(CShort(mFormPiecesOut.panBlue.pieces_num(i).Text) + 100)
          Next i
          ' red data
          For i = 0 To 4 * N - 1
            row = row & Chr(CDbl(red(i).Tag) + 100)
          Next i
          For i = 0 To 4 * N - 1
            row = row & Chr(ToPos(red(i).Top) * N + ToPos(red(i).Left) + 100)
          Next i
          For i = 0 To 11
            row = row & Chr(CShort(mFormPiecesOut.panRed.pieces_num(i).Text) + 100)
          Next i
          row = row & IIf(WaitForPlayer, "1", "0") ' who playes
          row = row & MakeNumNLen(nMoves, 3) ' no of moves
          f.WriteLine(row)
          f.Close()
        Catch ex As Exception
          MyMsgBox(My.Resources.MSG_GAME_NOT_SAVED & vbCrLf & Err.Description)
        End Try
      End If
    End With
  End Sub
  Sub RestoreGameFromSavedData(ByRef bReverse As Boolean)
    If Not Len(mSavedData) = 4 * 4 * N + 2 * 12 + 4 Then
      MyMsgBox(My.Resources.MSG_SAVED_DATA_INVALID)
      Exit Sub
    End If
    Dim i, pos As Integer
    Dim sp1, rt, bt, bp, rp, sp2 As String
    Dim p1, btag, xr, xb, yb, yr, rtag, p2 As Integer
    bt = Mid(mSavedData, 1, 4 * N) : mSavedData = Mid(mSavedData, 4 * N + 1)
    bp = Mid(mSavedData, 1, 4 * N) : mSavedData = Mid(mSavedData, 4 * N + 1)
    sp1 = Mid(mSavedData, 1, 12) : mSavedData = Mid(mSavedData, 12 + 1)
    rt = Mid(mSavedData, 1, 4 * N) : mSavedData = Mid(mSavedData, 4 * N + 1)
    rp = Mid(mSavedData, 1, 4 * N) : mSavedData = Mid(mSavedData, 4 * N + 1)
    sp2 = Mid(mSavedData, 1, 12) : mSavedData = Mid(mSavedData, 12 + 1)
    If bReverse Then
      Call SwapStr(bt, rt) : Call SwapStr(bp, rp) : Call SwapStr(sp1, sp2)
    End If
    For i = 0 To 4 * N - 1
      ' restore ranks
      btag = Asc(Mid(bt, i + 1, 1)) - 100
      rtag = Asc(Mid(rt, i + 1, 1)) - 100
      blue(i).Tag = btag
      red(i).Tag = rtag
      ' restore positions
      pos = Asc(Mid(bp, i + 1, 1)) - 100 : xb = pos Mod N : yb = pos \ N
      pos = Asc(Mid(rp, i + 1, 1)) - 100 : xr = pos Mod N : yr = pos \ N
      If bReverse Then
        xb = N - 1 - xb : yb = N - 1 - yb
        xr = N - 1 - xr : yr = N - 1 - yr
      End If
      blue(i).Left = ToPix(xb) : blue(i).Top = ToPix(yb)
      red(i).Left = ToPix(xr) : red(i).Top = ToPix(yr)
    Next
    ' restore eaten pieces
    For i = 0 To 11
      p1 = Asc(Mid(sp1, i + 1, 1)) - 100
      p2 = Asc(Mid(sp2, i + 1, 1)) - 100
      If p1 > 0 Then
        mFormPiecesOut.panBlue.pieces_num(i).Visible = True
        mFormPiecesOut.panBlue.pieces_num(i).Text = CStr(p1)
        Call mFormPiecesOut.panBlue.RestoreOutPiecePosition(i)
      Else
        mFormPiecesOut.panBlue.pieces_num(i).Visible = False
        mFormPiecesOut.panBlue.pieces_num(i).Text = "0"
        mFormPiecesOut.panBlue.pieces_out(i).Visible = False
      End If
      If p2 > 0 Then
        mFormPiecesOut.panRed.pieces_num(i).Visible = True
        mFormPiecesOut.panRed.pieces_num(i).Text = CStr(p2)
        Call mFormPiecesOut.panRed.RestoreOutPiecePosition(i)
      Else
        mFormPiecesOut.panRed.pieces_num(i).Visible = False
        mFormPiecesOut.panRed.pieces_num(i).Text = "0"
        mFormPiecesOut.panRed.pieces_out(i).Visible = False
      End If
    Next i
  End Sub
  Private Sub SwapStr(ByRef str1 As String, ByRef str2 As String)
    Dim t As String
    t = str1 : str1 = str2 : str2 = t
  End Sub
  Private Sub OnStop()
    'On Error Resume Next
    GameMode = enumGameMode.ABORTED
    If Connected Then
      SockClient.Send("#020code_quitegame")
    End If
  End Sub
  Private Sub ArrangeRandomly(ByRef PieceColor As Panel())
    Me.Cursor = System.Windows.Forms.Cursors.WaitCursor
    Dim b2, r2, t, r1, b1, i As Integer
    'Call HideRed
    Randomize(DateTime.Now.Ticks)
    Call DefineDefaultPieceTags(PieceColor)
    For i = 1 To 500
      ' Randomly swap piece types
      r1 = Rnd() * (4 * N - 1) : r2 = Rnd() * (4 * N - 1)
      b1 = Rnd() * (4 * N - 1) : b2 = Rnd() * (4 * N - 1)
      t = PieceColor(r1).Tag
      PieceColor(r1).Tag = PieceColor(r2).Tag
      PieceColor(r2).Tag = t
    Next i
    Me.Cursor = System.Windows.Forms.Cursors.Default
    ' remove out pieces and zero their labels
    If PieceColor(0).Name.StartsWith("_red_") Then
      Call mFormPiecesOut.panRed.ZeroPiecesLabels()
    Else
      Call mFormPiecesOut.panBlue.ZeroPiecesLabels()
    End If
  End Sub
  Private Sub StartNewGame(ByRef strdata As String)
    'On Error Resume Next
    VisitorName = Mid(strdata, 19)
    Connected = True
    Call PrepareGame()
  End Sub
  Public Sub PrepareGame()
    Dim ret As Integer
    Dim bReverse As Boolean
    Dim sWhoplayes, sMoves As String
    OpponentReady = False : OursReady = False
    Call board.Refresh() 'RedrawBoard()
    Call HideBlue()

    nMoves = 0
    hr = 0 : min = 0 : sec = 0
    WaitForPlayer = (Host = False)
    sblBattleInfo.Text = ""
    sblBattleInfo.Text = NickName & My.Resources.MSG_AGAINST & VisitorName
    tsbReady.Enabled = True

    If Not PlayOffline OrElse ArrangeMode = 1 Then 'kanoniki topothetisi
      If Len(mSavedData) > 0 Then ' restore game status from saved data !!
        bReverse = (Host = True)
        Call RestoreGameFromSavedData(bReverse) : Call ShowRed() : Call ShowMarkedBlue()
        sWhoplayes = Mid(mSavedData, 1, 1) : sMoves = Mid(mSavedData, 2)
        mSavedData = ""
        WaitForPlayer = ((sWhoplayes = "1" And Host = False) Or (sWhoplayes = "0" And Host = True))
        nMoves = CShort(sMoves)
        Call InitGame()
      Else ' not restoring saved game
        GameMode = enumGameMode.ARRANGEMENT
        ' back to normal
        'If Frame1.Top > Frame2.Top Then Call SwapPositions(Frame1, Frame2)
        Call mFormPiecesOut.panBlue.RestoreOutPiecePositions()
        Call mFormPiecesOut.panRed.RestoreOutPiecePositions()
        Call RemoveBlue() : Call RemoveRed()
        'Call SetLabelPos()
        CurrentPlayer = 2
        tsbReady.Visible = True
        'etoimos.Visible = True: etoimos.Enabled = True chkAllShown.Visible = True
        'Label2.Visible = False: Label4.Visible = False: lblMoves.Visible = False: lblTime.Visible = False
        'sb1.Style = mscomctl.SbarStyleConstants.sbrSimple
        sb1.Text = My.Resources.MSG_PREPARING_GAME
        redindex = 0 : blueindex = 0
        CurrentType = 0
        mFormPiecesOut.panRed.pieces_num(0).ForeColor = Color.Green
        If PlayOffline Then
          If Not DEBUGGING Then MyMsgBox(My.Resources.MSG_RED_PUTS_OFFLINE)
        Else
          'If Not DEBUGGING Then
          ret = MsgBox(My.Resources.MSG_RED_PUTS, MsgBoxStyle.Exclamation Or MsgBoxStyle.YesNo)
          ' for quick test or for bored people :)
          If ret = MsgBoxResult.No Then
            Call ArrangeRandomly(red) : Call ShowRed()
            Call MovePiecesDef(red) : redindex = 39 'Call etoimos_Click
          End If
          'End If
        End If
      End If ' restore saved game
    ElseIf PlayOffline And ArrangeMode = 2 Then  'tixaia topothetisi
      ' move pieces in the start positions
      Call ArrangeRandomly(red) : Call ArrangeRandomly(blue)
      Call ShowBlue() : Call ShowRed()
      Call MovePiecesDef(blue) : Call MovePiecesDef(red)
      Call InitGame()
    Else
      MyMsgBox("Error state in PrepareGame!!") ' this should not happen
    End If
  End Sub
  Private Sub OnReady()
    If GameMode = enumGameMode.ABORTED Then Exit Sub
    If PlayOffline And GameMode = enumGameMode.ARRANGEMENT Then
      If CurrentPlayer = 2 Then ' first red are positioned
        If redindex < 39 Then
          MyMsgBox(My.Resources.MSG_NOT_ALL_POSITIONED)
        Else
          Call NowPutBlue()
        End If
      ElseIf CurrentPlayer = 1 Then  ' then blue are positioned
        If blueindex < 39 Then
          MyMsgBox(My.Resources.MSG_NOT_ALL_POSITIONED)
        Else
          tsbReady.Enabled = False
          Me.Cursor = System.Windows.Forms.Cursors.WaitCursor
          Call ShowRed() : Call ShowBlue()
          Me.Cursor = System.Windows.Forms.Cursors.Default
          Call InitGame()
        End If
      End If ' CurrentPlayer
    Else 'on-line
      ' etoimos.Enabled = False chkAllShown.Visible = False
      If redindex < 39 Then
        MyMsgBox(My.Resources.MSG_NOT_ALL_POSITIONED)
      Else
        tsbReady.Enabled = False
        Call SendArrangement()
        ' Call MovePiecesDef(red) --> NO, pieces have been positioned
        OursReady = True
        If OpponentReady = True Then
          Call InitGame() ' ----------> GAME STARTES FROM HERE
        Else
          Call MyMsgBox(My.Resources.MSG_OPPONENT_INFORMED_READY)
        End If
      End If
    End If ' PlayOffline
  End Sub
  Sub NowPutBlue()
    Dim i As Integer
    Me.Cursor = System.Windows.Forms.Cursors.WaitCursor
    Call HideRed()
    For i = 0 To 11
      mFormPiecesOut.panRed.pieces_num(i).ForeColor = Color.Red
    Next i
    CurrentPlayer = 1
    CurrentType = 0 : mFormPiecesOut.panBlue.pieces_num(0).ForeColor = Color.Green
    Me.Cursor = System.Windows.Forms.Cursors.Default
    MyMsgBox(My.Resources.MSG_BLUE_PUTS)
  End Sub
  Public Sub InitGame()
    'On Error Resume Next
    nPlayer = 1
    If PlayOffline Then
      Host = True
    Else 'on-line game
      If nMoves = 0 Then
        Call MovePiecesDef(blue)
        Call mFormPiecesOut.panBlue.RemoveOutPieceLabels()
        Call mFormPiecesOut.panRed.RemoveOutPieceLabels()
        Call mFormPiecesOut.panBlue.RemoveOutPieces()
        Call mFormPiecesOut.panRed.RemoveOutPieces()
        Call mFormPiecesOut.panBlue.ZeroPiecesLabels()
        Call mFormPiecesOut.panRed.ZeroPiecesLabels()
      End If
      ' If chkAllShown.Value = 1 Then  Call ShowBlue 'only for debug
      '  Timer2.Interval = 1000
    End If
    mFormPiecesOut.panBlue.RestoreOutPiecePositions()
    mFormPiecesOut.panRed.RestoreOutPiecePositions()
    tsbReady.Visible = False
    'Label2.Visible = True: Label4.Visible = True: lblMoves.Visible = True: lblTime.Visible = True:TurnLabel.Visible = True
    'lblInfo.Visible = True: lblInfo.Caption = ""
    MoveFromNetwork = False
    Call ShowTurn()
    '''''Call SetLabelPos
    'reverse frame1 with respect to frame2
    'If Frame1.Top < Frame2.Top Then Call SwapPositions(Frame1, Frame2)
    Timer3.Enabled = True : Timer3.Interval = 1000
    If Not DEBUGGING Then Call MsgBox(My.Resources.MSG_GOOD_LUCK, MsgBoxStyle.OkOnly Or MsgBoxStyle.Information)
    Call PlaySound("Jagdhtte.wav")
    GameMode = enumGameMode.PLAYMODE
  End Sub
  'UPGRADE_NOTE: Form_Initialize was upgraded to Form_Initialize_Renamed. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="A9E4979A-37FA-4718-9994-97DD76ED70A7"'
  Private Sub Form_Initialize_Renamed()
    Dim strArg As String
    strArg = VB.Command()
    If strArg <> "" Then CheckArg(strArg)
    ' MsgBox App.Path
  End Sub
  Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
    Dim cx, cy As Integer
    cx = 520 : cy = 520
    Me.Location = New Point(20, 20)
    Me.Size = New Size(cx + 30, cy + Me.tb1.Height + Me.sb1.Height + 50)
    board.Location = New Point(10, tb1.Height + 10)
    board.Size = New Size(cx, cy)
    Call DefinePieces()
    'Frame1.SetBounds(cx + 20, 30, 0, 0, Windows.Forms.BoundsSpecified.X Or Windows.Forms.BoundsSpecified.Y) : Frame2.SetBounds(cx + 20, 290, 0, 0, Windows.Forms.BoundsSpecified.X Or Windows.Forms.BoundsSpecified.Y)
    'board.Scale (0, 0) - (10, 10)
    PieceSize.Width = board.Width / N : PieceSize.Height = board.Height / N
    mFormPiecesOut = New FormPiecesOut
    mFormPiecesOut.Show(Me)
    mFormPiecesOut.Location = New Point(Me.Right + 3, Me.Top)
    Call board.Refresh() 'RedrawBoard()
    'initialize number of pieces for each type
    GameMode = enumGameMode.NOTSTARTED
    CurrentType = 0
    Call LoadPieces()
    board.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch
    board.BackgroundImage = My.Resources.board ' System.Drawing.Image.FromFile("board.jpg")
    ' online
    Host = True
    ArrangeMode = 1
    HostName = "localhost"
    NickName = "Guest"
    VisitorName = "Opponent"
    PlayOffline = False
    'UPGRADE_ISSUE: MSComctlLib.StatusBar property sb1.Style was not upgraded. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="CC4C7EC0-C903-48FC-ACCC-81861D12DA4A"'
    'sb1.Style = mscomctl.SbarStyleConstants.sbrSimple
    ' prepare Panel used to form the image for panel
    Dim w, h As Integer
    w = sb1.Height : h = sb1.Height
  End Sub
  ' check program arguments
  Private Sub CheckArg(ByRef strdata As String)
    'On Error Resume Next
    Me.Visible = True
    Dim caseT, myname, hisname, hisIP As String
    Dim pos2, pos As Integer
    pos = InStr(10, Trim(strdata), "|", CompareMethod.Binary)
    myname = Mid(Trim(strdata), 10, pos - 10)
    pos2 = InStr(pos + 1, Trim(strdata), "|", CompareMethod.Binary)
    hisname = Mid(Trim(strdata), pos + 1, pos2 - pos)
    VisitorName = hisname
    NickName = myname
    PlayOffline = False
    caseT = Mid(strdata, 1, 9)
    If caseT = "|HostUsr|" Then
      Host = True
      SockListen.Close()
      'SockClient.Protocol = MSWinsockLib.ProtocolConstants.sckTCPProtocol
      SockListen.LocalPort = 777
      SockListen.Listen()
      WaitForPlayer = True
      frmTryConnect.GetinitWaitting()
      System.Windows.Forms.Application.DoEvents()
      frmTryConnect.ShowDialog()
    ElseIf caseT = "|HostTsr|" Then
      hisIP = Mid(Trim(strdata), pos2 + 1, Len(strdata))
      Host = False
      HostName = hisIP
      SockClient.RemotePort = 777
      SockClient.RemoteIP = HostName ' RemoteHost
      NameNIP.Connect()
      System.Windows.Forms.Application.DoEvents()
      frmTryConnect.GetinitWaitting()
      System.Windows.Forms.Application.DoEvents()
      frmTryConnect.ShowDialog()
    End If
  End Sub
  'positioning of pieces during arrangement
  Private Sub board_MouseDown(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.MouseEventArgs) Handles board.MouseDown
    Dim Button As Short = eventArgs.Button \ &H100000
    Dim Shift As Short = System.Windows.Forms.Control.ModifierKeys \ &H10000
    Dim x As Single = ToPosF(eventArgs.X - eventArgs.X Mod PieceSize.Width)
    Dim y As Single = ToPosF(eventArgs.Y - eventArgs.Y Mod PieceSize.Height)
    Dim ix, iy As Short 'blue
    Dim val_Left, posindex As Short
    If ArrangeMode = 1 AndAlso GameMode = enumGameMode.ARRANGEMENT Then
      ix = Math.Round(x) : iy = Math.Round(y)
      If CurrentPlayer = 1 Then
        val_Left = CShort(mFormPiecesOut.panBlue.pieces_num(CurrentType).Text)
        posindex = GetPosIndex(blue, ix, iy)
        If iy <= 3 And val_Left > 0 And FindTargetPiece(blue, ix, iy) = -1 Then
          blue(posindex).Tag = CurrentType
          Call ShowBlueOrRedPiece(blue(posindex))
          blue(posindex).Location = New Point(ToPix(ix), ToPix(iy))
          val_Left = val_Left - 1 : mFormPiecesOut.panBlue.pieces_num(CurrentType).Text = CStr(val_Left)
          blueindex = blueindex + 1
        End If
      ElseIf CurrentPlayer = 2 Then  'red
        val_Left = CShort(mFormPiecesOut.panRed.pieces_num(CurrentType).Text)
        ' posindex = redindex
        posindex = GetPosIndex(red, ix, iy)
        Debug.Assert(posindex >= 0, "Negative index")
        If iy >= 6 And val_Left > 0 And FindTargetPiece(red, ix, iy) = -1 Then
          red(posindex).Tag = CurrentType
          Call ShowBlueOrRedPiece(red(posindex))
          red(posindex).Location = New Point(ToPix(ix), ToPix(iy))
          val_Left = val_Left - 1
          mFormPiecesOut.panRed.pieces_num(CurrentType).Text = CStr(val_Left)
          redindex = redindex + 1
        End If
      End If
    End If
  End Sub
  Function GetPosIndex(ByRef PieceColor As Panel(), ByVal x As Short, ByVal y As Short) As Short
    If PieceColor(0).Name.StartsWith("_blue_") Then
      GetPosIndex = y * N + x
    Else
      GetPosIndex = (N - 1 - y) * N + (N - 1 - x)
    End If
  End Function
  Private Sub Form1_FormClosing(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    Dim cancel As Boolean = eventArgs.Cancel
    Dim UnloadMode As System.Windows.Forms.CloseReason = eventArgs.CloseReason
    Dim ret As String
    ret = CStr(MsgBox(My.Resources.MSG_ASK_EXIT, MsgBoxStyle.YesNo))
    If ret = CStr(MsgBoxResult.No) Then cancel = True
    eventArgs.Cancel = cancel
  End Sub
  Private Sub OnQuit()
    Dim ret As String
    'On Error Resume Next
    If Not DEBUGGING Then
      ret = CStr(MsgBox(My.Resources.MSG_ASK_EXIT, MsgBoxStyle.YesNo))
      If ret = CStr(MsgBoxResult.Yes) Then
        If Connected Then
          SockClient.Send("#020code_quitegame")
          System.Windows.Forms.Application.DoEvents()
          If SockClient.GetState <> Winsock_Control.WinsockStates.Connected Then SockClient.Close()
        End If
        End
      End If
    Else
      End
    End If
  End Sub
  Private Sub Form1_FormClosed(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
    frmChat1.Close()
    frmNewGame.Close()
    frmTryConnect.Close()
    NameNIP.Close()
  End Sub
  Private Sub OnHelp()
    help.Show()
  End Sub
  Private Sub PlaySound(ByVal SoundFile As String)
    Dim ret As Integer
    If tsbAllSounds.Checked = True Then
      Dim wavpath As String = String.Format("{0}\sounds\{1}", _
       My.Application.Info.DirectoryPath, SoundFile)
      ret = sndPlaySound(wavpath, SND_ASYNC Or SND_NODEFAULT)
    End If
  End Sub
  ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ what happens when a piece drops over a blue ! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Private Sub blue_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs)
    'On Error Resume Next
    Dim MoveString As String
    Dim nl, tl, tt, nt As Integer
    Dim tag1, tag2 As Integer
    Dim source As Panel = e.Data.GetData(GetType(Panel))
    Dim Index As Integer = Array.IndexOf(blue, sender)
    tag1 = source.Tag And &HFS
    tag2 = blue(Index).Tag And &HFS
    Dim xnew, xold, yold, ynew As Integer
    If GameMode = enumGameMode.PLAYMODE Then
      If source.Name.StartsWith("_red_") And WaitForPlayer = False And AllowMove(ToPos(source.Left), ToPos(source.Top), ToPos(blue(Index).Left), ToPos(blue(Index).Top)) And tag1 < 10 Then
        WaitForPlayer = True : Call ShowTurn()
        xold = ToPos(source.Left)
        yold = ToPos(source.Top)
        ' These coords are relative to blue piece, not to board !!
        'xnew = CInt(x - 0.45): ynew = CInt(y - 0.45)
        xnew = ToPos(blue(Index).Left)
        ynew = ToPos(blue(Index).Top)
        If Not PlayOffline And Connected Then
          MoveString = "#010_code_move" & Array.IndexOf(red, source) & "-" & xold & "-" & yold & "-" & xnew & "-" & ynew
          Call PieceMoved(MoveString)
          System.Windows.Forms.Application.DoEvents()
        End If
        Call Battle(blue(Index), source)
      End If
    ElseIf ArrangeMode = 1 AndAlso GameMode = enumGameMode.ARRANGEMENT AndAlso _
     CurrentPlayer = 1 AndAlso source.Name.StartsWith("_blue_") Then  ' swap their values
      tl = ToPos(source.Left) : tt = ToPos(source.Top) : nl = ToPos(blue(Index).Left) : nt = ToPos(blue(Index).Top)
      If tl <> nl Or tt <> nt Then
        source.Tag = tag2
        blue(Index).Tag = tag1
        Call ShowBlueOrRedPiece(source) : Call ShowBlueOrRedPiece(blue(Index))
      End If
    End If
  End Sub
  ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ what happens when a piece drops over a red !  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Private Sub red_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs)
    Dim tag1, nl, tl, tt, nt, tag2 As Integer
    Dim xnew, xold, yold, ynew As Integer
    Dim source As Panel = e.Data.GetData(GetType(Panel))
    Dim Index As Integer = Array.IndexOf(red, CType(sender, Panel))
    'On Error Resume Next
    tag1 = source.Tag And &HFS
    tag2 = red(Index).Tag And &HFS

    If GameMode = enumGameMode.PLAYMODE Then
      xold = CShort(ToPos(source.Left)) : yold = CShort(ToPos(source.Top))
      If MoveFromNetwork Then
        xnew = e.X : ynew = e.Y
      Else
        xnew = ToPos(red(Index).Left) : ynew = ToPos(red(Index).Top)
      End If
      If ((PlayOffline Or MoveFromNetwork) AndAlso source.Name.StartsWith("_blue_") AndAlso _
       WaitForPlayer = True) AndAlso (AllowMove(xold, yold, xnew, ynew) AndAlso tag1 < 10) Then
        WaitForPlayer = Not WaitForPlayer : ShowTurn()
        Call Battle(red(Index), source)
        If Not PlayOffline And Connected Then
          Call board.Refresh() 'RedrawBoard()
          Call DrawMoveArrow(xold, yold, xnew, ynew)
        End If
      End If
      ' during ARRANGEMENT swap their values
    ElseIf ArrangeMode = 1 AndAlso GameMode = enumGameMode.ARRANGEMENT AndAlso _
     CurrentPlayer = 2 And source.Name.StartsWith("_red_") Then  'swap their values
      tl = ToPos(source.Left)
      tt = ToPos(source.Top)
      nl = ToPos(red(Index).Left)
      nt = ToPos(red(Index).Top)
      'Source.Move nl, nt: red(Index).Move tl, tt
      If tl <> nl Or tt <> nt Then
        source.Tag = tag2
        red(Index).Tag = tag1
        Call ShowBlueOrRedPiece(source) : Call ShowBlueOrRedPiece(red(Index))
      End If
    End If
  End Sub
  Private Sub piece_DragOver(ByVal sender As Object, ByVal e As DragEventArgs)
    If e.Data.GetDataPresent(GetType(Panel)) Then
      e.Effect = DragDropEffects.Move
    End If
  End Sub
  Private Sub board_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) _
   Handles board.DragOver
    If e.Data.GetDataPresent(GetType(Panel)) Then
      e.Effect = DragDropEffects.Move
    End If
  End Sub
  ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ what happens when a piece drops over the board ! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Private Sub board_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) _
   Handles board.DragDrop
    ' only pieces on board can move - not flag, not bombs
    Dim xnew, xold, yold, ynew As Integer
    Dim xnewF, ynewF As Single
    Dim dx, dy As Integer
    Dim tag1 As Integer
    Dim MoveString As String
    Dim NoMove As Boolean
    Dim source As Panel = e.Data.GetData(GetType(Panel))
    xold = ToPos(source.Left) : yold = ToPos(source.Top)
    If MoveFromNetwork Then
      xnew = e.X : ynew = e.Y
      dx = xnew - xold : dy = ynew - yold
    Else
      Dim ptBoard As Point = board.PointToClient(New Point(e.X, e.Y))
      ptBoard.Offset(mOffPoint) ' offset the drag pos relative to pic pos
      xnewF = ToPosF(ptBoard.X) : ynewF = ToPosF(ptBoard.Y)
      dx = Math.Round(Math.Abs(xnewF - xold))
      dy = Math.Round(Math.Abs(ynewF - yold))
      xnew = xold + Math.Sign(xnewF - xold) * dx
      ynew = yold + Math.Sign(ynewF - yold) * dy
    End If
    Trace.WriteLine(String.Format("{0}-{1}->{2}-{3}->{4}-{5}", _
     xold, yold, xnewF, ynewF, xnew, ynew))

    tag1 = source.Tag And &HFS

    NoMove = True
    Dim posindex As Short
    If GameMode = enumGameMode.PLAYMODE Then
      If ((source.Name.StartsWith("_red_") AndAlso WaitForPlayer = False) OrElse _
       ((PlayOffline Or MoveFromNetwork) AndAlso source.Name.StartsWith("_blue_") AndAlso WaitForPlayer = True)) AndAlso _
        NotInLake(xnew, ynew) AndAlso (tag1 <> 10 And tag1 <> 11) Then
        ' move piece
        If tag1 = 0 Then 'anagnwristis
          If AllowMoveAnagnoristi(xold, yold, xnew, ynew) Then
            If dx > 1 Or dy > 1 Then
              Call PlaySound("Crazed.wav")
              Call ShowBlueOrRedPiece(source)
              If Not PlayOffline AndAlso source.Name.StartsWith("_red_") Then
                Call DrawBorderOnPiece(source, True)
              End If
            Else
              Call PlaySound("play.wav")
            End If
            NoMove = False
          End If
        ElseIf AllowMove(xold, yold, xnew, ynew) Then  ' any other piece except anagnoristis
          Call PlaySound("play.wav")
          NoMove = False
        End If
      End If
      If NoMove Then
        MessageBeep(MB_ICONASTERISK)
      Else
        source.Location = New Point(ToPix(xnew), ToPix(ynew))
        If Not PlayOffline AndAlso Connected Then
          If source.Name.StartsWith("_red_") Then
            MoveString = "#010_code_move" & Array.IndexOf(red, source) & "-" & xold & "-" & yold & "-" & xnew & "-" & ynew
            Call PieceMoved(MoveString) 'send our move
            System.Windows.Forms.Application.DoEvents()
          Else ' source = blue
            Call board.Refresh() 'RedrawBoard()
            Call DrawMoveArrow(xold, yold, xnew, ynew)
          End If
        End If
        WaitForPlayer = Not WaitForPlayer : ShowTurn()
      End If
      Exit Sub
    ElseIf ArrangeMode = 1 And GameMode = enumGameMode.ARRANGEMENT Then
      If FindTargetPiece(blue, xnew, ynew) = -1 And FindTargetPiece(red, xnew, ynew) = -1 Then
        If CurrentPlayer = 1 And source.Name.StartsWith("_blue_") Then
          If ynew <= 3 Then
            posindex = GetPosIndex(blue, xnew, ynew)
            blue(posindex).Tag = tag1
            Call ShowBlueOrRedPiece(blue(posindex))
            source.Location = New Point(ToPix(-2), ToPix(-2))
            blue(posindex).Location = New Point(ToPix(xnew), ToPix(ynew))
          End If
        ElseIf CurrentPlayer = 2 AndAlso source.Name.StartsWith("_red_") Then
          If ynew >= 6 Then
            posindex = GetPosIndex(red, xnew, ynew)
            red(posindex).Tag = tag1
            Call ShowBlueOrRedPiece(red(posindex))
            source.Location = New Point(ToPix(-2), ToPix(-2))
            red(posindex).Location = New Point(ToPix(xnew), ToPix(ynew))
          End If
        End If
      End If
    End If

  End Sub
  Sub DefinePieces()
    Call AssignNames() ' global function in modMessages
    Dim i As Integer
    For i = 0 To 11
      pionia(i).fname = PieceNames(i)
      pionia(i).desc = PieceDescriptions(i)
    Next i
  End Sub
  Sub MovePiecesDef(ByRef ColorPiece As Panel())
    Dim x, i, j, y As Integer
    'move blue or red pieces at default positions
    For i = 0 To 3
      For j = 0 To N - 1
        If ColorPiece(0).Name.StartsWith("_blue_") Then
          x = ToPix(j)
          y = ToPix(i)
        Else
          x = ToPix(N - 1 - j)
          y = ToPix(N - 1 - i)
        End If
        ColorPiece(i * N + j).Location = New Point(x, y)
      Next j
    Next i
  End Sub
  Sub LoadPieces()
    Dim i As Integer
    ' load pionia from 1 to 39
    '    red(0).Visible = True : blue(0).Visible = True
    ReDim red(4 * N - 1)
    ReDim blue(4 * N - 1)
    red(0) = Me._red_0 : blue(0) = Me._blue_0
    red(0).Left = ToPix(-2) : blue(0).Left = ToPix(-2) ' hide 2 template pionia
    red(0).Size = PieceSize
    For i = 1 To 4 * N - 1
      red(i) = New Panel  ' use red(0) as template
      blue(i) = New Panel   ' use blue(0) as template
      red(i).Name = "_red_" & i : blue(i).Name = "_blue_" & i
      AddHandler blue(i).MouseDown, AddressOf _blue_or_red_MouseDown
      AddHandler red(i).MouseDown, AddressOf _blue_or_red_MouseDown
      AddHandler blue(i).GiveFeedback, AddressOf _blue_or_red_GiveFeedback
      AddHandler red(i).GiveFeedback, AddressOf _blue_or_red_GiveFeedback
      AddHandler blue(i).DragOver, AddressOf piece_DragOver
      AddHandler red(i).DragOver, AddressOf piece_DragOver
      AddHandler blue(i).DragDrop, AddressOf blue_DragDrop
      AddHandler red(i).DragDrop, AddressOf red_DragDrop
      AddHandler blue(i).Paint, AddressOf piece_Paint
      AddHandler red(i).Paint, AddressOf piece_Paint
      red(i).BorderStyle = red(0).BorderStyle
      blue(i).BorderStyle = blue(0).BorderStyle
      red(i).BackgroundImageLayout = ImageLayout.Stretch
      blue(i).BackgroundImageLayout = ImageLayout.Stretch
      red(i).AllowDrop = True : blue(i).AllowDrop = True
      red(i).Cursor = red(0).Cursor : blue(i).Cursor = blue(0).Cursor
      red(i).Size = red(0).Size : blue(i).Size = blue(0).Size
      red(i).Location = New Point(-100, -100) : blue(i).Location = red(i).Location
      board.Controls.Add(red(i)) : board.Controls.Add(blue(i))
    Next i
    ' define pieces
    Call DefineDefaultPieceTags(blue) : Call DefineDefaultPieceTags(red)
  End Sub
  Sub DefineDefaultPieceTags(ByRef PieceColor As Panel())
    Dim i2, i1, nt, k As Integer
    i1 = 0
    For nt = 0 To 11
      i2 = i1 + typepieces(nt) - 1
      For k = i1 To i2
        PieceColor(k).Tag = nt
        'red(k).Tag = nt
        'fblue = "erot" & "_1.gif"
        'blue(k).Picture = LoadPicture(fblue)
      Next k
      i1 = i1 + typepieces(nt)
    Next nt
  End Sub

  Sub RemoveBlue()
    Dim k As Integer
    For k = 0 To 4 * N - 1
      blue(k).Location = New Point(ToPix(-2), ToPix(-2))
    Next k
  End Sub
  Sub RemoveRed()
    Dim k As Integer
    For k = 0 To 4 * N - 1
      red(k).Location = New Point(ToPix(-2), ToPix(-2))
    Next k
  End Sub
  ' set ? image
  Sub HideBlue()
    Dim k As Integer
    'fb = "erot_1.gif"
    For k = 0 To 4 * N - 1
      blue(k).BackgroundImage = My.Resources.erot_1 'System.Drawing.Image.FromFile(fb)
      ToolTip1.SetToolTip(blue(k), My.Resources.MSG_HIDDEN)
    Next k
  End Sub
  ' set ? image
  Sub HideRed()
    Dim k As Integer
    'fb = "erot_2.gif"
    For k = 0 To 4 * N - 1
      red(k).BackgroundImage = My.Resources.erot_2 'System.Drawing.Image.FromFile(fb)
      ToolTip1.SetToolTip(red(k), My.Resources.MSG_HIDDEN)
    Next k
  End Sub

  ' show blue images
  Sub ShowBlue()
    Dim k As Integer
    For k = 0 To 4 * N - 1
      Call ShowBlueOrRedPiece(blue(k))
    Next k
  End Sub
  Sub ShowBlueOrRedPiece(ByRef p As System.Windows.Forms.Panel)
    Dim nt As Integer
    Dim picname, suffix As String
    nt = p.Tag And &HFS ' tag (low nibble) holds the kind of piece
    If p.Name.StartsWith("_blue_") Then
      suffix = "_1" '.gif"
    Else
      suffix = "_2" '.gif"
    End If
    picname = pionia(nt).fname & suffix
    p.BackgroundImage = My.Resources.ResourceManager.GetObject(picname) 'System.Drawing.Image.FromFile(picname)
    ToolTip1.SetToolTip(p, pionia(nt).desc)
    If (p.Tag And &H10S) AndAlso p.Name.StartsWith("_red_") AndAlso Not PlayOffline Then
      Call DrawBorderOnPiece(p, False)
    End If
  End Sub
  ' a piece that won a battle must be shown
  Sub DrawBorderOnPiece(ByRef p As Panel, ByRef bSendMessage As Boolean)
    Dim cenY, cenX, r As Single
    cenX = ToPos(p.ClientRectangle.Width) / 2 - 1
    cenY = ToPos(p.ClientRectangle.Height) / 2 - 1
    r = ToPos(p.ClientRectangle.Width) / 2 - 1
    Dim pen As New Pen(Color.FromArgb(255, 255, 0, 255), 3)
    Dim g As Graphics = p.CreateGraphics()
    ''p.Circle (cenX, cenY), r, color
    g.DrawRectangle(pen, 0, 0, p.Width - 3, p.Height - 3) ', color, B
    p.Tag = p.Tag Or &H10S ' mark piece as shown by puting a one in the high nibble
    Debug.Assert(p.Name.StartsWith("_red_"), "Internal error: border should be sent only for red pieces")
    If bSendMessage And Not PlayOffline Then
      SockClient.Send("#010_code_tagc" & Array.IndexOf(red, p) & "," & p.Tag)
      System.Windows.Forms.Application.DoEvents()
      Call Sleep(200)
    End If
    pen.Dispose()
    g.Dispose()
  End Sub
  Sub RedrawBoard(Optional ByVal g As Graphics = Nothing)
    ' redraw entire board
    Dim i As Integer
    Dim pic As Image
    If g Is Nothing Then g = Me.CreateGraphics()
    ' board.Line (0, 0)-(N, N), board.BackColor, BF
    ' draw board lines
    board.ForeColor = Color.Black
    'UPGRADE_ISSUE: Panel property board.DrawWidth was not upgraded. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="CC4C7EC0-C903-48FC-ACCC-81861D12DA4A"'
    For i = 1 To N - 1
      g.DrawLine(Pens.Black, ToPix(i), 0, ToPix(i), ToPix(N))
      g.DrawLine(Pens.Black, 0, ToPix(i), ToPix(N), ToPix(i))
    Next
    pic = My.Resources.lake 'System.Drawing.Image.FromFile("lake.jpg")
    ' draw lakes
    g.DrawImage(pic, ToPix(2), ToPix(4), ToPix(2), ToPix(2))
    g.DrawImage(pic, ToPix(6), ToPix(4), ToPix(2), ToPix(2))
    'board.Line (2, 4)-Step(2, 2), , B
    'board.Line (6, 4)-Step(2, 2), , B
  End Sub
  Sub DrawMoveArrow(ByRef xold As Short, ByRef yold As Short, ByRef xnew As Short, ByRef ynew As Short)
    Dim dx, x, y, dy As Single
    Dim Y1, X1, X2, Y2 As Single
    Dim y3, x3, x4, y4 As Single
    Dim sx, sy As Short
    Dim of_Renamed As Single
    ' this routine used the BoardPixY now ToPix
    x = ToPixF(CSng(xold) + 0.5)
    y = ToPixF(CSng(yold) + 0.5)
    Dim pen As New Pen(Color.FromArgb(255, 255, 255, 0), 3)
    Dim g As Graphics = board.CreateGraphics()
    Const b As Short = 13 : Const b1 As Short = 10 : Const b2 As Short = 6
    dx = xnew - xold
    dy = ynew - yold
    If dx = 0 Then
      sy = dy / System.Math.Abs(dy) : of_Renamed = IIf(sy > 0, 0, ToPix(1))
      X1 = x : X2 = x : Y1 = y - sy * b : Y2 = ToPix(ynew) + of_Renamed - sy * 3
      x3 = x - b2 : x4 = x + b2 : y3 = Y2 - sy * b1 : y4 = y3
    Else
      sx = dx / System.Math.Abs(dx) : of_Renamed = IIf(sx > 0, 0, ToPix(1))
      X1 = x - sx * b : X2 = ToPix(xnew) + of_Renamed - sx * 3 : Y1 = y : Y2 = y
      x3 = X2 - sx * b1 : x4 = x3 : y3 = y - b2 : y4 = y + b2
    End If
    g.DrawLine(pen, X1, Y1, X2, Y2)
    g.DrawLine(pen, x3, y3, X2, Y2)
    g.DrawLine(pen, x4, y4, X2, Y2)
    'board.Line (x1, y1)-(x2, y2)
    'board.Line (x3, y3)-(x2, y2)
    'board.Line (x4, y4)-(x2, y2)
    g.Dispose()
  End Sub
  ' show blue images
  Sub ShowRed()
    Dim k As Integer
    For k = 0 To 4 * N - 1
      Call ShowBlueOrRedPiece(red(k))
    Next
  End Sub
  Sub ShowMarkedBlue()
    Dim k As Integer
    For k = 0 To 4 * N - 1
      ' show only marked pieces
      If blue(k).Tag And &H10S Then
        Call ShowBlueOrRedPiece(blue(k))
      End If
    Next k
  End Sub
  Sub SwapPositions(ByRef c1 As System.Windows.Forms.Control, ByRef c2 As System.Windows.Forms.Control)
    Dim tl, tt As Integer
    tl = c1.Left : c1.Left = c2.Left : c2.Left = tl
    tt = c1.Top : c1.Top = c2.Top : c2.Top = tt
  End Sub
  Function NotInLake(ByVal xnew As Short, ByVal ynew As Short) As Boolean
    NotInLake = ((xnew < 2 Or xnew > 3) And (xnew < 6 Or xnew > 7)) Or (ynew < 4 Or ynew > 5)
  End Function
  Function AllowMove(ByVal xold As Short, ByVal yold As Short, ByVal xnew As Short, ByVal ynew As Short) As Boolean
    Dim dx, dy As Integer
    dx = System.Math.Abs(xnew - xold) : dy = System.Math.Abs(ynew - yold)
    AllowMove = (dx = 0 And dy = 1) Or (dx = 1 And dy = 0)
  End Function
  Function AllowMoveAnagnoristi(ByVal xold As Short, ByVal yold As Short, ByVal xnew As Short, ByVal ynew As Short) As Boolean
    AllowMoveAnagnoristi = True
    Dim x, dx, dy, y As Integer
    Dim Y1, X1, X2, Y2 As Integer

    dx = System.Math.Abs(xnew - xold) : dy = System.Math.Abs(ynew - yold)
    If Not ((dx >= 1 And dy = 0) Or (dy >= 1 And dx = 0)) Then
      AllowMoveAnagnoristi = False
      Exit Function
    Else
      If dx > 1 Then
        If xnew > xold Then
          X1 = xold : X2 = xnew
        Else
          X1 = xnew : X2 = xold
        End If
        For x = X1 + 1 To X2 - 1 ' no pieces between
          If FindTargetPiece(red, x, ynew) > -1 Or FindTargetPiece(blue, x, ynew) > -1 Then
            AllowMoveAnagnoristi = False
            Exit Function
          End If
        Next
      ElseIf dy > 1 Then
        If ynew > yold Then
          Y1 = yold : Y2 = ynew
        Else
          Y1 = ynew : Y2 = yold
        End If
        For y = Y1 + 1 To Y2 - 1 ' no pieces between
          If FindTargetPiece(red, xnew, y) > -1 Or FindTargetPiece(blue, xnew, y) > -1 Then
            AllowMoveAnagnoristi = False
            Exit Function
          End If
        Next y
      End If
    End If
  End Function
  ' p2 attacks
  Function Battle(ByRef p1 As Panel, ByRef p2 As Panel) As Short
    Dim tag1, tag2 As Integer
    Dim winner As Integer
    Dim sSound As String = ""
    tag1 = p1.Tag And &HFS
    tag2 = p2.Tag And &HFS
    If tag1 = aksies.SHMAIA Then
      winner = 2
      GameMode = enumGameMode.FINISHED
    ElseIf tag1 = aksies.BOMBA Then  ' vomva
      If tag2 = aksies.DYNAMITISTIS Then winner = 2 Else winner = 1
      'o kataskopos ta trwei ola otan epitithetai kai to antistrofo
    ElseIf tag2 = aksies.KATASKOPOS And tag1 = aksies.KATASKOPOS Then
      winner = 2
    ElseIf tag2 = aksies.KATASKOPOS Or tag1 = aksies.KATASKOPOS Then
      winner = 2
    ElseIf tag1 = tag2 Then  'could be simply else
      winner = 0
    ElseIf tag1 < tag2 Then  'ierarxia
      winner = 2
    ElseIf tag1 > tag2 Then  'ierarxia
      winner = 1
    End If
    oRepl = Nothing
    If winner = 1 Then
      oGarb1 = p2
      oRepl = p1
      bMoveOnEat = False
      EatPiece(p2)
    ElseIf winner = 2 Then
      oGarb1 = p1
      oRepl = p2
      bMoveOnEat = True
      EatPiece(p1)
      'p2.Move p1.Left, p1.Top ' now in GarbageTimer
    ElseIf winner = 0 Then
      oGarb1 = p1 : oGarb2 = p2
      EatPiece(p1) : EatPiece(p2)
    End If
    If winner = 1 AndAlso p1.Name.StartsWith("_blue_") Then
      Call ShowBlueOrRedPiece(p1)
      sWinner = "blue"
      sblBattleInfo.Text = My.Resources.MSG_LOST_BATTLE & PieceDescriptions(tag2)
    ElseIf winner = 2 AndAlso p2.Name.StartsWith("_blue_") Then
      Call ShowBlueOrRedPiece(p2)
      sWinner = "blue"
      sblBattleInfo.Text = My.Resources.MSG_LOST_BATTLE & PieceDescriptions(tag1)
    ElseIf winner <> 0 Then  ' winner is the red
      sWinner = "red"
      If winner = 1 Then
        sblBattleInfo.Text = My.Resources.MSG_WON_BATTLE & PieceDescriptions(tag2)
        If Not PlayOffline Then Call DrawBorderOnPiece(p1, True)
      Else
        sblBattleInfo.Text = My.Resources.MSG_WON_BATTLE & PieceDescriptions(tag1)
        If Not PlayOffline Then Call DrawBorderOnPiece(p2, True)
      End If
    Else ' winner=0
      sWinner = "both"
      sblBattleInfo.Text = My.Resources.MSG_EQUAL_BATTLE & PieceDescriptions(tag1)
    End If
    ' play appropriate sounds
    If tag1 = aksies.BOMBA And winner = 2 Then
      sSound = "CHERRY2"
    ElseIf tag1 = aksies.BOMBA And winner = 1 Then
      sSound = "boom"
    ElseIf tag2 = aksies.KATASKOPOS Or tag1 = aksies.KATASKOPOS Then
      sSound = "xfile2"
    ElseIf (Not PlayOffline AndAlso sWinner = "red") OrElse _
     (PlayOffline And winner = 2) Then
      sSound = "Triumph"
    ElseIf (Not PlayOffline AndAlso sWinner = "blue") OrElse _
     (PlayOffline And winner = 1) Then
      sSound = "toc"
    ElseIf sWinner = "both" Then
      sSound = "brams2"
    End If
    Call PlaySound(sSound & ".wav")
    Battle = winner
  End Function
  Sub CheckIfNoMovePossible()
    ' check if some player has no pieces to move, in that case finish the game
    Dim i, tag1 As Integer
    Dim bRedHasToMove, bBlueHasToMove As Boolean
    If Not GameMode = enumGameMode.PLAYMODE Then Exit Sub
    bRedHasToMove = False : bBlueHasToMove = False
    For i = 0 To 4 * N - 1
      tag1 = red(i).Tag And &HFS
      If tag1 < aksies.BOMBA AndAlso ToPos(red(i).Left) >= 0 AndAlso _
       ToPos(red(i).Left) < N AndAlso ToPos(red(i).Top) >= 0 AndAlso ToPos(red(i).Top) < N Then
        If CanMakeMove(red(i)) Then
          bRedHasToMove = True
          Exit For
        End If
      End If
    Next i
    If Not bRedHasToMove Then
      MyMsgBox(My.Resources.MSG_NO_RED_CAN_MOVE)
      GameMode = enumGameMode.FINISHED
      sWinner = "blue"
    End If
    For i = 0 To 4 * N - 1
      tag1 = blue(i).Tag And &HFS
      If tag1 < aksies.BOMBA AndAlso ToPos(blue(i).Left) >= 0 AndAlso ToPos(blue(i).Left) < N _
       AndAlso ToPos(blue(i).Top) >= 0 AndAlso ToPos(blue(i).Top) < N Then
        If CanMakeMove(blue(i)) Then
          bBlueHasToMove = True
          Exit For
        End If
      End If
    Next i
    If Not bBlueHasToMove Then
      MyMsgBox(My.Resources.MSG_NO_BLUE_CAN_MOVE)
      GameMode = enumGameMode.FINISHED
      sWinner = "red"
    End If
  End Sub
  Function CanMakeMove(ByRef p As System.Windows.Forms.Panel) As Boolean
    Dim x, y As Integer
    Dim target As Panel()
    x = ToPos(p.Left) : y = ToPos(p.Top)
    If p.Name.StartsWith("_red_") Then
      target = red
    Else
      target = blue
    End If

    If x > 0 And FindTargetPiece(target, x - 1, y) = -1 Then
      CanMakeMove = True
      Exit Function
    End If
    If x < N - 1 And FindTargetPiece(target, x + 1, y) = -1 Then
      CanMakeMove = True
      Exit Function
    End If
    If y > 0 And FindTargetPiece(target, x, y - 1) = -1 Then
      CanMakeMove = True
      Exit Function
    End If
    If y < N - 1 And FindTargetPiece(target, x, y + 1) = -1 Then
      CanMakeMove = True
      Exit Function
    End If
  End Function
  Sub EatPiece(ByRef p As System.Windows.Forms.Panel)
    Dim val_Left As Integer
    Dim tag1 As Integer
    tag1 = p.Tag And &HFS
    If p.Name.StartsWith("_blue_") Then Call ShowBlueOrRedPiece(p)
    Dim g As Graphics = p.CreateGraphics()
    Dim pen As New Pen(Color.FromArgb(255, 255, 0, 255), 2)
    g.DrawLine(pen, 0, 0, p.Width, p.Height)
    g.DrawLine(pen, 0, p.Height, p.Width, 0)
    TimerGarbage.Enabled = True
    'p.Move -2, -2 ' now in garbageTimer
    ' increase number of eaten pieces of king p.tag
    If p.Name.StartsWith("_blue_") Then
      val_Left = CShort(mFormPiecesOut.panBlue.pieces_num(tag1).Text)
      If val_Left = 0 Then
        Call mFormPiecesOut.panBlue.RestoreOutPiecePosition(tag1)
        mFormPiecesOut.panBlue.pieces_num(tag1).Visible = True
      End If
      val_Left = val_Left - 1 : mFormPiecesOut.panBlue.pieces_num(tag1).Text = CStr(val_Left)
    ElseIf p.Name.StartsWith("_red_") Then
      val_Left = CShort(mFormPiecesOut.panRed.pieces_num(tag1).Text)
      If val_Left = 0 Then
        Call mFormPiecesOut.panRed.RestoreOutPiecePosition(tag1)
        mFormPiecesOut.panRed.pieces_num(tag1).Visible = True
      End If
      val_Left = val_Left - 1
      mFormPiecesOut.panRed.pieces_num(tag1).Text = CStr(val_Left)
    End If
    pen.Dispose()
    g.Dispose()
  End Sub
  Sub FinishGame()
    'TurnLabel.Visible = False: turn(0).Visible = False: turn(1).Visible = False
    sblTurn.Image = Nothing
    Timer3.Enabled = False
    GameMode = enumGameMode.FINISHED
    If Not PlayOffline And sWinner = "blue" Then
      If PlayOffline Then : MyMsgBox(My.Resources.MSG_BLUE_WON)
      Else : MyMsgBox(My.Resources.MSG_I_LOST)
      End If
      Call PlaySound("isp_ipox.wav")
    Else
      If PlayOffline Then : MyMsgBox(My.Resources.MSG_RED_WON)
      Else : MyMsgBox(My.Resources.MSG_I_WON)
      End If
      Call PlaySound("allilouia.wav")
    End If
    Call ShowBlue()
    Call board.Refresh() 'RedrawBoard()
    Timer3.Enabled = False
  End Sub
  Sub ShowTurn()
    Dim col As Color
    Dim s2 As String
    s2 = My.Resources.MSG_TURN
    If WaitForPlayer Then
      col = Color.Red
      sblTurn.Image = My.Resources.turn_red
      sblTurn.Text = "Turn: Blue"
    Else
      col = Color.Blue
      sblTurn.Image = My.Resources.turn_blue
      sblTurn.Text = "Turn: Red"
    End If
    ' Dim pen As New Pen(col, 2)
    'Dim brush As New SolidBrush(col)
    ' Dim g As Graphics = Graphics.FromImage(sblTurn.Image)
    'g.FillRectangle(Brush, sblTurn.Bounds)
    'g.DrawString(s2, sb1.Font, Brushes.Black, 0, 2)
    'g.DrawLine(pen, g.MeasureString(s2, sb1.Font).Width + 5, 0, picSb2.Width, picSb2.Height)
    sblMoves.Text = "Moves: " & CStr(nMoves)
    nMoves = nMoves + 1
    ' brush.Dispose()
    ' g.Dispose()
  End Sub

  Private Sub tsbNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbNew.Click
    OnStart()
  End Sub

  Private Sub tsbSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbSave.Click
    OnSave()
  End Sub

  Private Sub tsbReady_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbReady.Click
    OnReady()
  End Sub

  Private Sub tsbChat_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbChat.Click
    OnChat()
  End Sub

  Private Sub tsbHelp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbHelp.Click
    OnHelp()
  End Sub

  Private Sub tsbQuit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbQuit.Click
    OnQuit()
  End Sub

  Private Sub board_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles board.Paint
    Me.RedrawBoard(e.Graphics)
  End Sub

  Private mOffPoint As Point
  Private Sub _blue_or_red_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
    Dim p As Panel = CType(sender, Panel)
    Dim data As New DataObject(p)
    mOffPoint = New Point(-e.X, -e.Y)
    p.DoDragDrop(data, DragDropEffects.All)
  End Sub
  Private Sub _blue_or_red_GiveFeedback(ByVal sender As Object, ByVal e As GiveFeedbackEventArgs)
    e.UseDefaultCursors = False
    System.Windows.Forms.Cursor.Current = Cursors.SizeAll
  End Sub

  Private Sub piece_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
    Dim p As Panel = sender
    Dim g As Graphics = p.CreateGraphics() 'e.Graphics
    g.DrawEllipse(Pens.Pink, p.Bounds)
    g.Dispose()
  End Sub

  Private Sub tsbPieces_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbPieces.Click

  End Sub

  Private Sub tsbAllSounds_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbAllSounds.Click

  End Sub

  Private Sub tsbStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbStop.Click
    OnStop()
  End Sub

  Private Sub sb1_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs)

  End Sub
End Class